imx: add cpu-freq SIP runtime service support
authorAnson Huang <[email protected]>
Tue, 15 Jan 2019 02:56:36 +0000 (10:56 +0800)
committerAnson Huang <[email protected]>
Thu, 17 Jan 2019 02:49:48 +0000 (10:49 +0800)
On i.MX8QM/i.MX8QX with system controller inside, the CPU's clock
rate is managed by SCFW(system controller firmware) and can ONLY be
changed from secure world, so SIP runtime service is needed for
setting CPU's clock rate, this patch adds cpu-freq SIP runtime service
support.

Signed-off-by: Anson Huang <[email protected]>
plat/imx/common/imx_sip_handler.c
plat/imx/common/imx_sip_svc.c
plat/imx/common/include/imx_sip_svc.h

index a414a4467ceb4e9416fd2d66b4ab1960ac51382d..22a7f2b83bc1e2253a904a7672897183955b7a7f 100644 (file)
 #include <imx_sip_svc.h>
 #include <sci/sci.h>
 
+#ifdef PLAT_IMX8QM
+const static int ap_cluster_index[PLATFORM_CLUSTER_COUNT] = {
+       SC_R_A53, SC_R_A72,
+};
+#endif
+
 static int imx_srtc_set_time(uint32_t year_mon,
                        unsigned long day_hour,
                        unsigned long min_sec)
@@ -42,3 +48,31 @@ int imx_srtc_handler(uint32_t smc_fid,
 
        SMC_RET1(handle, ret);
 }
+
+static void imx_cpufreq_set_target(uint32_t cluster_id, unsigned long freq)
+{
+       sc_pm_clock_rate_t rate = (sc_pm_clock_rate_t)freq;
+
+#ifdef PLAT_IMX8QM
+       sc_pm_set_clock_rate(ipc_handle, ap_cluster_index[cluster_id], SC_PM_CLK_CPU, &rate);
+#endif
+#ifdef PLAT_IMX8QX
+       sc_pm_set_clock_rate(ipc_handle, SC_R_A35, SC_PM_CLK_CPU, &rate);
+#endif
+}
+
+int imx_cpufreq_handler(uint32_t smc_fid,
+                   u_register_t x1,
+                   u_register_t x2,
+                   u_register_t x3)
+{
+       switch (x1) {
+       case IMX_SIP_SET_CPUFREQ:
+               imx_cpufreq_set_target(x2, x3);
+               break;
+       default:
+               return SMC_UNK;
+       }
+
+       return 0;
+}
index 23ff0bbef4fba57ed72d7cae474ee91b0cd4c4ad..89b9df8c55bcceed562d49928dffacab949edfaf 100644 (file)
@@ -29,6 +29,9 @@ static uintptr_t imx_sip_handler(unsigned int smc_fid,
 #if (defined(PLAT_IMX8QM) || defined(PLAT_IMX8QX))
        case  IMX_SIP_SRTC:
                return imx_srtc_handler(smc_fid, handle, x1, x2, x3, x4);
+       case  IMX_SIP_CPUFREQ:
+               SMC_RET1(handle, imx_cpufreq_handler(smc_fid, x1, x2, x3));
+               break;
 #endif
        default:
                WARN("Unimplemented i.MX SiP Service Call: 0x%x\n", smc_fid);
index 0d21f7562cda3c24d450ce0339781a2f09a0e492..4ba7b87acf0ff9d2b1281374e917c62d158652a2 100644 (file)
@@ -8,10 +8,15 @@
 #define __IMX_SIP_SVC_H__
 
 /* SMC function IDs for SiP Service queries */
+#define IMX_SIP_CPUFREQ                        0xC2000001
+#define IMX_SIP_SET_CPUFREQ            0x00
+
 #define IMX_SIP_SRTC                   0xC2000002
 #define IMX_SIP_SRTC_SET_TIME          0x00
 
 #if (defined(PLAT_IMX8QM) || defined(PLAT_IMX8QX))
+int imx_cpufreq_handler(uint32_t smc_fid, u_register_t x1,
+                       u_register_t x2, u_register_t x3);
 int imx_srtc_handler(uint32_t smc_fid, void *handle, u_register_t x1,
                     u_register_t x2, u_register_t x3, u_register_t x4);
 #endif